package org.example.car.system.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.example.car.system.config.JwtUtils;
import org.example.car.system.config.MinioUtils;
import org.example.car.system.config.Result;
import org.example.car.system.domain.ProvinceCityDistrict;
import org.example.car.system.domain.User;
import org.example.car.system.service.ProvinceCityDistrictService;
import org.example.car.system.service.UserPostService;
import org.example.car.system.service.UserRoleService;
import org.example.car.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: cy
 * @Date: 2024/6/19 14:58
 */
@CrossOrigin
@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private UserService userService;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserPostService userPostService;
    @Autowired
    private ProvinceCityDistrictService provinceCityDistrictService;

    /**
     * 查询所有用户接口
     *
     * @return
     */
    @RequestMapping("/selectAll")
    public Result selectAll(@RequestParam(defaultValue = "1") Integer pageNum, @RequestBody User entity) {
        PageHelper.startPage(pageNum, 5);
        List<User> users = userService.selectAll(entity);
        return Result.success(new PageInfo<>(users));
    }

    @RequestMapping("/getRoleIds")
    public List<Integer> getRoleIds(Integer userId){
        List<Integer> roleId = userRoleService.getRoleIds(userId);
        return roleId;
    }

    @RequestMapping("/getPostIds")
    public List<Integer> getPostIds(Integer userId){
        List<Integer> postIds = userPostService.getPostIds(userId);
        return postIds;
    }

    /**
     * 添加用户接口
     *
     * @return
     */
    @RequestMapping("/instr")
    public Result instr(@RequestBody User entity) {
        boolean b = userService.insertUser(entity);
        return b ? Result.success() : Result.fail();
    }

    /**
     * 根据id删除用户
     *
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public Result delete(Integer id) {
        boolean b = userService.delete(id);
        return b ? Result.success() : Result.fail();
    }

    /**
     * 根据id修改用户
     *
     * @param entity 用户对象
     * @return
     */
    @RequestMapping("/updateById")
    public Result updateById(@RequestBody User entity) {
        boolean b = userService.updateById(entity);
        return b ? Result.success() : Result.fail();
    }

    /**
     * 头像上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/upload")
    public String upload(MultipartFile file) throws Exception {
        return minioUtils.upload(file);
    }

    /**
     * 普通登录
     *
     * @param entity
     * @return
     */
    @RequestMapping("/login")
    public Result login(@RequestBody User entity) {
        User userDB = userService.selectByName(entity);
        if (userDB == null) {
            return Result.fail("用户名不存在");
        }

        String pwd = DigestUtil.md5Hex(entity.getPassword());
        if (!userDB.getPassword().equals(pwd)) {
            return Result.fail("密码输入有误");
        }

        //判断验证码
        String redisCode = (String) redisTemplate.opsForValue().get(entity.getUid());
        if (redisCode == null) {
            return Result.fail("验证码已过期,请重新获取");
        }
        if (!redisCode.equals(entity.getCode())) {
            return Result.fail("验证码输入有误");
        }

        String token = JwtUtils.createToken(userDB);
        return Result.success(token);
    }

    /**
     * 获取验证码
     *
     * @param uid
     * @param response
     * @throws IOException
     */
    @RequestMapping("/createCode")
    public void createCode(String uid, HttpServletResponse response) throws IOException {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
        //CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
        //图形验证码写出，可以写出到文件，也可以写出到流
        captcha.write(response.getOutputStream());
        //给验证码存入redis 并设置两分钟过期时间
        redisTemplate.opsForValue().set(uid, captcha.getCode(), 30, TimeUnit.SECONDS);
    }

    /**
     * 树形菜单
     * @return
     */
    @RequestMapping("/getAreaAll")
    public List<Tree<String>> getAreaAll() {
        List<ProvinceCityDistrict> list = provinceCityDistrictService.selectAll();

        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都有默认值的
        treeNodeConfig.setChildrenKey("children");
        treeNodeConfig.setIdKey("value");
        treeNodeConfig.setNameKey("label");
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        //转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.<ProvinceCityDistrict, String>build(list, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId()+"");
                    tree.setParentId(treeNode.getPid()+"");
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
//                    tree.putExtra("extraField", 666);
//                    tree.putExtra("other", new Object());
                });
        return treeNodes;
    }

    //生成excel
    @RequestMapping("/createExcel")
    public void createExcel(HttpServletResponse response) throws IOException {
        List<User> users = userService.selectAlls();

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").doWrite(users);
    }

    //逻辑删除
    @RequestMapping("/delFlag")
    public Result delFlag(Integer id) {
        boolean b = userService.delFlag(id);
        return b ? Result.success() : Result.fail();
    }

    //读取excel
//    @PostMapping("/readExcel")
//    public Map<String, Object> readExcel(MultipartFile file) throws IOException {
//
//        Map<String, Object> map = new HashMap<>();
//        try {
//            map.put("code",200);
//            EasyExcel.read(file.getInputStream(), User.class,new DataListener(userService)).sheet().doRead();
//        }catch (IOException exception){
//            map.put("code",500);
//            exception.printStackTrace();
//        }
//        return map;
//    }
}
